Cloudflare Workers で Next.js アプリ開発

Cloudflare Workers で Next.js アプリ開発

Clock Icon2024.11.07

こんにちは、@TakaakiKakei です。

今回は、Cloudflare Workers で Next.js アプリを構築する流れを解説します。

Cloudflare Workers とは

Cloudflare Workers は、Cloudflare が提供するサーバーレスのエッジコンピューティングプラットフォームです。サーバー管理の煩わしさから解放され、運用コストの削減も期待できます。エッジロケーションでコードを実行するため、ユーザーに近い場所で処理が行われ、低レイテンシと優れた負荷分散を実現します。開発者フレンドリーな設計により、迅速なデプロイとインターネットへの公開が可能です。

無料プランの注意点: Cloudflare Workers の無料プランでは、デプロイ可能なファイルサイズが 1MiB に制限されています。今回は、この制限を超えるため、有料プランを利用して検証を行います。

Next.js とは

Next.js は、React ベースの Web アプリケーションフレームワークとして世界中で広く採用されています。豊富なリソース、活発なコミュニティ、そして Vercel のエコシステムとのシームレスな統合が魅力です。Vercel AI SDK や shadcn/ui などの強力なライブラリを活用することで、開発を効率化できます。

やってみた

1. Cloudflare Workers で Next.js アプリを作成

Cloudflare Workers の公式ドキュメントに沿って、Next.js アプリを作成します。

  1. ターミナルを開き、プロジェクトフォルダに移動します。
cd <プロジェクトフォルダ>
  1. 次のコマンドを実行し、アプリを作成します。ここでは、アプリ名を solo-dev-ai-chat とし、デプロイは行いません (no を選択)。
pnpm create cloudflare@latest solo-dev-ai-chat --framework=next --experimental

実行中、デプロイに関する質問が表示されますが、「no」を選択してスキップします。

  1. プロジェクトフォルダ内に、以下のファイルとディレクトリが作成されます (node_modules は省略)。
solo-dev-ai-chat/
├── src
│   └── app
│       └── page.tsx
├── wrangler.toml
├── tsconfig.json
├── package.json
└── public
    └── favicon.ico
  1. お好みのエディタでプロジェクトを開きます。今回は Cursor を使用します。エディタのターミナルで以下のコマンドを実行し、開発サーバーを起動します。
pnpm run dev
  1. ブラウザで http://localhost:3000/ にアクセスし、デフォルトの Next.js アプリケーションが表示されれば成功です。

CleanShot 2024-11-07 at 16.28.47@2x.png

2. デプロイ

  1. まず、wrangler コマンドを使用して、Cloudflare アカウントにログインします。"assets.bucket" is a required field. というエラーが表示される場合がありますが、今回は無視して構いません。
wrangler login
  1. エディタのターミナルで以下のコマンドを実行し、アプリをデプロイします。
pnpm run deploy

無料プランの場合: 無料プランで Workers を使用している場合、Your Worker exceeded the size limit of 1 MiB というエラーが表示されます。これは、無料プランでは 1MiB を超えるファイルをデプロイできないためです。続行するには、有料プランへのアップグレードが必要です。

  1. デプロイが完了すると、ターミナルにデプロイ先の URL が表示されます。ブラウザでその URL にアクセスし、アプリが正常に動作することを確認します。

CleanShot 2024-11-07 at 16.26.51@2x.png

3. AI チャット機能の実装

シンプルな AI チャット機能を実装し、アプリケーションに付加価値を加えてみましょう。ここでは、OpenAI の API と Vercel AI SDK を使用します。

  1. OpenAI API キーの取得

https://platform.openai.com/api-keys から OpenAI の API キーを取得します。API キーは機密情報のため、安全に保管してください。

  1. Vercel AI SDK

Vercel AI SDK は、OpenAI をはじめ、主要な LLM プロバイダーの API を簡単に利用できるようにする SDK です: https://sdk.vercel.ai/providers/ai-sdk-providers/openai

  1. Vercel AI SDK のインストール:
pnpm add ai @ai-sdk/openai
  1. src/app/page.tsx は不要なので削除します。

  2. src/app/(chat)/layout.tsx を作成し、チャット機能のレイアウトを定義します。

"use client";

interface ChatLayoutProps {
  children: React.ReactNode;
}

export default function ChatLayout({ children }: ChatLayoutProps) {
  return <div>{children}</div>;
}
  1. src/app/(chat)/page.tsx を作成し、チャット機能のページを実装します。
import ChatUI from "@/components/chat/ui";

export default function ChatPage() {
  return <ChatUI />;
}
  1. src/components/chat/ui.tsx を作成し、チャット UI を実装します。参考として、https://sdk.vercel.ai/docs/ai-sdk-ui/chatbot#example を参考にできます。
"use client";

import { useChat } from "ai/react";

export default function ChatUI() {
  const { messages, input, handleInputChange, handleSubmit } = useChat();
  return (
    <div className="flex flex-col w-full max-w-md py-24 mx-auto stretch">
      {messages.map((m) => (
        <div key={m.id} className="whitespace-pre-wrap">
          {m.role === "user" ? "User: " : "AI: "}
          {m.content}
        </div>
      ))}

      <form onSubmit={handleSubmit}>
        <input
          className="fixed bottom-0 w-full max-w-md p-2 mb-8 border border-gray-300 rounded shadow-xl"
          value={input}
          placeholder="Say something..."
          onChange={handleInputChange}
        />
      </form>
    </div>
  );
}
  1. src/app/(chat)/api/chat/route.ts を作成し、AI チャット API を実装します。こちらも、https://sdk.vercel.ai/docs/ai-sdk-ui/chatbot#example を参考にできます。ここでは、gpt-4o-mini モデルを使用し、環境変数から OpenAI API キーを読み込むように設定しています。
import { createOpenAI } from "@ai-sdk/openai";
import { streamText, Message } from "ai";
export const maxDuration = 30;

export async function POST(req: Request) {
  const { messages } = (await req.json()) as { messages: Message[] };

  const openai = createOpenAI({
    apiKey: process.env.OPENAI_API_KEY,
  });

  const result = await streamText({
    model: openai("gpt-4o-mini"),
    messages,
  });

  return result.toDataStreamResponse();
}
  1. .env.local ファイルを作成し、OpenAI の API キーを環境変数として設定します。
OPENAI_API_KEY=sk-xxxxx
  1. 開発サーバーを起動します。
pnpm run dev
  1. ブラウザで http://localhost:3000/chat にアクセスし、AI チャット機能が動作することを確認します。

CleanShot 2024-11-06 at 15.38.48@2x.png

  1. アプリをデプロイします。
pnpm run deploy

この段階では、AI チャット機能はまだ動作しません。Cloudflare Workers に OpenAI の API キーが設定されていないためです。

  1. Cloudflare Workers でシークレットを設定

    • Cloudflare Workers のダッシュボードにアクセスし、対象のアプリ (solo-dev-ai-chat) を開きます。
    • 設定 > 変数とシークレット から、シークレットを追加します。
    • タイプ は シークレット、キー は OPENAI_API_KEY、値 は .env.local に設定した OpenAI の API キーを入力します。
    • 展開 ボタンをクリックして変更をデプロイします。
  2. デプロイが完了すると、AI チャット機能が動作するようになります。

  3. 認証が実装されていない状態なので、アクセスされると誰でもチャットできてしまいます。検証後は設定したシークレットを削除するか、アプリケーション自体を削除してください。アプリケーションは、設定ページ下部の 削除 ボタンから削除できます。

まとめ

Cloudflare Workers を使用して Next.js アプリを構築し、AI チャット機能を実装する手順を紹介しました。今回作成したコードは、GitHub で公開しています。他の機能も随時追加予定です。

認証機能は Cloudflare Access を利用することで容易に実装できます。また、Vercel のエコシステムには、shadcn/ui という UI コンポーネントライブラリが豊富に用意されており、組み合わせることでよりデザイン性の高いアプリケーションを構築できます。これらの詳細についても、今後発信したいと思います。

この記事が、皆さんの開発の参考になれば幸いです。それではまた!

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.